package main;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * @author Abner
 * @date 2021/9/21 20:24
 * @email songkd90@163.com
 * @description 自定义加载器加载执行 Hello.xlass文件
 */
public class ExerciseWeek01 extends ClassLoader{

    public static void main(String[] args) {
        Class<?> clazz = new ExerciseWeek01().findClass("Hello");
        try {
            Object instance = clazz.newInstance();
            Method method = clazz.getMethod("hello");
            method.invoke(instance);
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        }

    }

    /**
     * 类加载
     * @param name
     * @return
     */
    @Override
    protected Class<?> findClass(String name) {
        String path = System.getProperty("user.dir");
        String fileName = "Hello.xlass";
        byte[] bytes = loadFileAsBytes(path + File.separator + "src" + File.separator + "file" + File.separator + fileName);
        byte[] converted = convertFile(bytes);
        return super.defineClass(name, converted, 0, converted.length);
    }

    /**
     * 加载文件为 byte[]
     * @param filePath
     * @return
     */
    private static byte[] loadFileAsBytes(String filePath){
        File file = new File(filePath);
        byte[] byteArray = null;
        FileInputStream fis = null;
        try {
            byteArray = new byte[(int) file.length()];
            fis = new FileInputStream(file);
            fis.read(byteArray);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                fis.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        return byteArray;
    }

    /**
     * 文件解密 x = 255 - x
     * @param bytes
     * @return
     */
    private static byte[] convertFile(byte[] bytes) {
        byte[] result = new byte[bytes.length];
        for (int i = 0; i < bytes.length; i++) {
            bytes[i] = (byte) (0xff - (bytes[i] & 0xff));
        }
        return bytes;
    }
}
